package com.JVM核心机制;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 *
 *
 * @author jiangbang
 * @date 2016/10/18
 */
public class 自定义类加载器 extends ClassLoader{
    private String rootDir;

    public 自定义类加载器(String rootDir) {
        this.rootDir = rootDir;
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        Class<?> c = findLoadedClass(name);

        //应该要先查询有没有加载过这个类，如果已经加载，则直接返回加载好的类，如果没有，加载新的类
        if(c!=null){
            return c;
        }else{
            ClassLoader parent = this.getParent();
            c = parent.loadClass(name);  //委派给父类加载
            if(c!=null){
                return c;
            }else{
              byte[] classData = getClassData(name);
                if(classData == null){
                    throw new ClassNotFoundException();
                }else{
                    c = defineClass(name,classData,0,classData.length);
                }
            }
        }
        return super.findClass(name);
    }

    private byte[] getClassData(String classname){   //com.bjsxt.test.User   d:/myjava/  com/bjsxt/test/User.class
        String path = rootDir +"/"+ classname.replace('.', '/')+".class";

//		IOUtils,可以使用它将流中的数据转成字节数组
        InputStream is = null;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try{
            is  = new FileInputStream(path);

            byte[] buffer = new byte[1024];
            int temp=0;
            while((temp=is.read(buffer))!=-1){
                baos.write(buffer, 0, temp);
            }

            return baos.toByteArray();
        }catch(Exception e){
            e.printStackTrace();
            return null;
        }finally{
            try {
                if(is!=null){
                    is.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(baos!=null){
                    baos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
